package io.summer.gadget.channel.core;

import io.summer.redis.tool.RedisTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Set;

/**
 * @author Moonlight
 */
@Slf4j
public abstract class AbstractServiceHelper {
  private final static String SERVICE_PREFIX = "summer:service:";
  private final static String TOPIC_PREFIX = "summer:topic:";

  String getTopicAllKey() {
    return TOPIC_PREFIX + "*";
  }

  String getTopicKey(String topic) {
    return TOPIC_PREFIX + topic;
  }

  String getServiceAllKey() {
    return SERVICE_PREFIX + "*";
  }

  String getServiceKey(String appName) {
    return SERVICE_PREFIX + appName;
  }

  String getAppName(String serviceKey) {
    return serviceKey.replace(SERVICE_PREFIX, "");
  }

  @Autowired
  private RedisTool redisTool;

  void registerServer(String appName, String server) {
    redisTool.hash().increment(getServiceKey(appName), server, 1);
  }

  private boolean removeService(String serviceKey, String server) {
    Object v = redisTool.hash().get(serviceKey, server);
    if (v == null) {
      return false;
    }
    int n = Integer.parseInt((String) v);
    n--;
    boolean hasIns = n > 0;
    if (hasIns) {
      redisTool.hash().put(serviceKey, server, n);
    }
    return hasIns;
  }

  void unregisterServer(String appName, String server) {
    String k = getServiceKey(appName);
    if (!removeService(k, server)) {
      log.info("no server exist any more: {}@{}", k, server);
      redisTool.hash().delete(k, server);
    }
    if (redisTool.hash().keys(k).isEmpty()) {
      Set<String> ss = redisTool.stringTemplate().keys(TOPIC_PREFIX + "*");
      log.info("no service: {}. remove all topic: {}", appName, ss);
      assert ss != null;
      for (String s : ss) {
        redisTool.hash().delete(s, appName);
      }
    }
  }

  UriComponents parseUrl(String url) {
    return UriComponentsBuilder.fromHttpUrl(url).build();
  }
}
